#!/usr/bin/perl
use strict;

#données
my $dossier = $ARGV[0];
my ($ligne, $mot, $cat, $lemme, $occur, @spr, $file, @dos, $compt, $dos_s, $file_d, @file, $fileres);
my $temp;
my %classif_lemme; #beta
my %compt_lemme; #occurences des lemmes par fichiers
my %compt_files_lemme; #occurences totales de lemmes par fichier
my %compt_classe_lemme; #occurences totales de lemmes par classe
my %etiquettes; #etiquettes
my %new_etiquettes; #nouvelles etiquettes calculées
my %nombre_docs; #nombre de documents, par classe et total
my %appartenances; #quels mots dans quels fichiers;
my %choix_alea; #découpage du corpus en lots
my $doc_ap = 0;
my $doc_test = 0;
my $epsilon = 0.01;

$nombre_docs{"0-star"} = 135;
$nombre_docs{"1-star"} = 283;
$nombre_docs{"2-star"} = 394;
$nombre_docs{"3-star"} = 173;
$nombre_docs{"unsupervised"} = 4021;
$nombre_docs{"total"} = $nombre_docs{"0-star"} + $nombre_docs{"1-star"} + $nombre_docs{"2-star"} + $nombre_docs{"3-star"};

#on va etiqueter les unsupervised
$doc_test = $nombre_docs{"unsupervised"};

#Lecture des dossiers
opendir(DIR, $dossier) || die "can't opendir $dossier: $!";
@spr = grep { /supervised$/ } readdir(DIR);
closedir DIR;

#Récupération des lots de docs
sub load_lots(){
	my $file = "lots";
	open TT, $file or die "Cannot open $file\n";
	while($ligne = <TT>) {
		if($ligne=~ /^(.*)\t(.*)$/){
			my $fil = $1; my $lot = $2;
			$choix_alea{$fil} = $lot;
			$doc_ap++;
		}
	}
	print "Lots charges: $doc_ap docs apprentissage, $doc_test docs test\n";
}

#Récupération des differents comptes dans le corpus
sub classif_bayesien()
{
	my $tot3 = 0;
	print "Classif...\n";
	#parcours les dossiers
	foreach my $element (@spr){
		my $element2 = $dossier."/".$element;
		if($element2 eq $dossier."/supervised"){
			opendir(DIR, $element2) || die "can't opendir $element2: $!";
			print "Traitement de $element2 ...\n";
			@dos = grep { /star/ } readdir(DIR);
			closedir DIR;
		}
		else{
			@dos = @spr;
			$element2 = $dossier;
		}
		
		foreach $dos_s (@dos){
			my $dos_s2 = $element2."/".$dos_s;
			opendir(DIR, $dos_s2) || die "can't opendir $dos_s2: $!";
			print "Traitement de $dos_s2 ...\n";
			@file = grep { /txt.lemme$/ } readdir(DIR);
			closedir DIR;
			
					
			# chaque fichier
			foreach $file_d (@file){
				my $file_d2 = $dos_s2."/".$file_d;
				
				#On récupère les etiquettes des documents supervisés
				if($file_d2 =~ /0-star/){
					$etiquettes{$file_d2} = "0-star";
				}
				if($file_d2 =~ /1-star/){
					$etiquettes{$file_d2} = "1-star";
				}
				if($file_d2 =~ /2-star/){
					$etiquettes{$file_d2} = "2-star";
				}
				if($file_d2 =~ /3-star/){
					$etiquettes{$file_d2} = "3-star";
				}
				
				open TT, $file_d2 or die "Cannot open $file_d2\n";
				while($ligne = <TT>) {
					if($ligne=~ /^(.*)\t(.*)\t(.*)$/){
						$mot = $1; $cat = $2; $lemme = $3;
						if((($cat) !~ /,/) && (($cat) !~ /:/) && (($cat) !~ /SENT/) && (($cat) !~ /''/)){
							if(!exists($appartenances{$file_d2}{$lemme})){
								$appartenances{$file_d2}{$lemme} = 1;
							}
							#nombre de lemmes dans chaque fichier
							if(exists($compt_files_lemme{$file_d2})){
								$compt_files_lemme{$file_d2}++;
							}
							else{
								$compt_files_lemme{$file_d2}=1;
							}
							#occurrences du lemme dans chaque fichier
							if(exists($compt_lemme{$lemme}{$file_d2})){
								$compt_lemme{$lemme}{$file_d2}++;
							}
							else{
								$compt_lemme{$lemme}{$file_d2}=1;
							}
						}
					}
				}
			}
		}
	}
	
	#On récupère le nombre de lemmes par classe
	$compt_classe_lemme{"0-star"}=0;
	$compt_classe_lemme{"1-star"}=0;
	$compt_classe_lemme{"2-star"}=0;
	$compt_classe_lemme{"3-star"}=0;
	
	foreach my $file (keys(%compt_files_lemme)){
		if($file =~ /0-star/){
			$compt_classe_lemme{"0-star"} += $compt_files_lemme{$file};
		}
		if($file =~ /1-star/){
			$compt_classe_lemme{"1-star"} += $compt_files_lemme{$file};
		}
		if($file =~ /2-star/){
			$compt_classe_lemme{"2-star"} += $compt_files_lemme{$file};
		}
		if($file =~ /3-star/){
			$compt_classe_lemme{"3-star"} += $compt_files_lemme{$file};
		}
	}
}


#Calcul des betas: fréquences en occurences, non normalisées
sub calcul_parametres(){
	print "Début param...\n";
	
		foreach my $element (keys(%compt_lemme)){
			my $a=0;
			my $b=0;
			my $c=0;
			my $d=0;
			my $tot3 = 0;
			foreach $file(keys(%{$compt_lemme{$element}})){
				#on utilise que les lots d'apprentissage
				if(exists($choix_alea{$file})){
					if($etiquettes{$file} eq "0-star"){
						$a += $compt_lemme{$element}{$file};
						}
					else{
						if($etiquettes{$file} eq "1-star"){
							$b += $compt_lemme{$element}{$file};
							}
						else{
							if($etiquettes{$file} eq "2-star"){
								$c += $compt_lemme{$element}{$file};
								}
							else{
								if($etiquettes{$file} eq "3-star"){
									$d += $compt_lemme{$element}{$file};
									}
								}}}
					}
				}
			if($a == 0){ $a = $epsilon;}
			if($b == 0){ $b = $epsilon;}
			if($c == 0){ $c = $epsilon;}
			if($d == 0){ $d = $epsilon;}
			$classif_lemme{$element}{"0-star"} = $a / $compt_classe_lemme{"0-star"};
			$classif_lemme{$element}{"1-star"} = $b / $compt_classe_lemme{"1-star"};
			$classif_lemme{$element}{"2-star"} = $c / $compt_classe_lemme{"2-star"};
			$classif_lemme{$element}{"3-star"} = $d / $compt_classe_lemme{"3-star"};
		}
	print "Fin param...\n";
}

#etiquetage des données avec les paramètres calculés
sub etiquetage(){
	$fileres = "Etiquetage.txt";
	my $reussite = 0;
	my $compt_file = 0;
	foreach my $element (@spr){
		my $element2 = $dossier."/".$element;
		if($element2 eq $dossier."/supervised"){
			opendir(DIR, $element2) || die "can't opendir $element2: $!";
			print "Traitement de $element2 ...\n";
			@dos = grep { /star/ } readdir(DIR);
			closedir DIR;
		}
		else{
			@dos = @spr;
			$element2 = $dossier;
		}
		
		foreach $dos_s (@dos){
			my $dos_s2 = $element2."/".$dos_s;
			opendir(DIR, $dos_s2) || die "can't opendir $dos_s2: $!";
			print "Traitement de $dos_s2 ...\n";
			@file = grep { /lemme$/ } readdir(DIR);
			closedir DIR;
				
			# chaque fichier
			foreach $file_d (@file){
				my $file_d2 = $dos_s2."/".$file_d;
		
				#on ne traite que les documents non supervisés (ne faisant pas parti des lots)
				if(!exists($choix_alea{$file_d2})){
					$compt_file++;
					my %res;
					$res{"0-star"}=0;
					$res{"1-star"}=0;
					$res{"2-star"}=0;
					$res{"3-star"}=0;
					
					foreach $lemme (keys(%classif_lemme)){
						if(exists($compt_lemme{$lemme}{$file_d2})){
							$res{"0-star"} = $res{"0-star"} + ($compt_lemme{$lemme}{$file_d2} / $compt_files_lemme{$file_d2}) * log($classif_lemme{$lemme}{"0-star"});
							$res{"1-star"} = $res{"1-star"} + ($compt_lemme{$lemme}{$file_d2} / $compt_files_lemme{$file_d2})* log($classif_lemme{$lemme}{"1-star"});
							$res{"2-star"} = $res{"2-star"} + ($compt_lemme{$lemme}{$file_d2} / $compt_files_lemme{$file_d2}) * log($classif_lemme{$lemme}{"2-star"});
							$res{"3-star"} = $res{"3-star"} + ($compt_lemme{$lemme}{$file_d2} / $compt_files_lemme{$file_d2}) * log($classif_lemme{$lemme}{"3-star"});
						}
					}
					
									
					#on trie les resultats dans l'ordre décroissant, et on prendra le max
					my @resFinal = (sort { $res{$b} <=> $res{$a} } keys(%res));
					#on vient de trouver une nouvelle etiquette
					$new_etiquettes{$file_d2} = $resFinal[0];
				}
			}
		}
		#on sauvegarde ces nouvelles étiquettes que l'on utisera à l'étape suivante
		open (N_ETIQ, ">new_etiquettes_unsupervised") or die "Can't open new_etiquettes!\n";
		foreach my $file (keys(%new_etiquettes)){
			print N_ETIQ $file."\t".$new_etiquettes{$file}."\n";
		}
		close(N_ETIQ);
	}
}

###### Main #############
load_lots();
classif_bayesien();
calcul_parametres();
etiquetage();

